from Tkinter import *
import Task
import datetime
import time
import pickle
import os
import copy
from tkFileDialog import askopenfilename
from tkFileDialog import asksaveasfilename

class Panel(object):
	
	def __init__(self, bg="light blue", width = 1000, height = 700, fontsize=10, lineColor = "red", textColor = "white"):
		self.bg = bg
		self.width = width
		self.height = height
		self.lineColor = lineColor
		self.textColor = textColor
		self.itemList = []
		self.lineDict = {}
		self.lineList = []
		self.textList = []
		self.isFlagged = False
		self.fontsize = fontsize
		self.taskList = []
		self.projectDict = {}
		self.fileName = ""
		
		self.initializeFrame()
		self.moveAllTasks()
		self.addButton()
		self.canvas.pack()
		self.tk.mainloop()
	
	def deleteTask(self, task):
		self.taskList.remove(task)
		if isinstance(task, Task.ProjectTask):
			del self.projectDict[task]
		self.moveAllTasks()

	def addButton(self):
		topFrame = Frame(self.tk)
		topFrame.pack()
		taskButton = Button(topFrame, text = "New Task", command = self.createTaskPopup, width=self.width/60)
		projectButton = Button(topFrame, text = "New Project", command = self.createProjectTaskPopup, width=self.width/60)
		subtaskButton = Button(topFrame, text = "New Project Subtask", command = self.createSubtaskPopup, width=self.width/60)
		saveButton = Button(topFrame,  text = "Save", command=self.savePanel, width=self.width/60)
		openButton = Button(topFrame,  text = "Open", command=self.openPanel, width=self.width/60)
		saveAsButton = Button(topFrame,  text = "Save As", command=self.savePanel2, width=self.width/60)
		
		openButton.pack(side=LEFT)	
		saveButton.pack(side=LEFT)	
		saveAsButton.pack(side=LEFT)
		taskButton.pack(side=LEFT)
		projectButton.pack(side=LEFT)
		subtaskButton.pack(side=LEFT)

	def printsomething(self):
		print 'something'

	def parseDateTime(self, dateString):
		sections = dateString.split("/")
		try:
			return datetime.datetime(int(sections[2]), int(sections[0]), int(sections[1]))
		except:
			return datetime.datetime(datetime.datetime.today().year, datetime.datetime.today().month, datetime.datetime.today().day + 1)

	def lowerLines(self):
		for line in self.lineList:
			self.canvas.lower(line)

	def createTaskPopup(self):
		self.currentTaskType = "Task"
		self.createPopup()
		
	def createSubtaskPopup(self):
		self.currentTaskType = "Subtask"
		self.createPopup()
		
	def createProjectTaskPopup(self):
		self.currentTaskType = "Project"
		self.createPopup()

	def createPopup(self):
		self.editPopup = Tk()
		self.editPopup.title('Create ' + self.currentTaskType)
		
		name = Label(self.editPopup, text = "Name ")
		self.nameEntry = Entry(self.editPopup, width=25)
		
		description = Label(self.editPopup, text = "Description")
		self.descriptionEntry = Text(self.editPopup, width = 28, height = 3)		
		
		hoursCompleted = Label(self.editPopup, text = "Hours Completed")
		self.hoursCompletedEntry = Entry(self.editPopup, width= 3)
		
		hoursTotal = Label(self.editPopup, text = "Hours Total")
		self.hoursTotalEntry = Entry(self.editPopup, width= 3)
		
		dueDate = Label(self.editPopup, text = "Due (MM/DD/YYYY)")
		self.dueDateEntry = Entry(self.editPopup, width = 10)
		self.dueDateEntry.insert(0, str(datetime.datetime.today().month) + "/" + str(datetime.datetime.today().day + 1) + "/" + str(datetime.datetime.today().year))
		
		createButton = Button(self.editPopup, text = "Create " + self.currentTaskType, command=self.createTask)
		
		self.editPopup.bind("<KeyPress-Return>", self.helpCreateTask)
		
		checkButton = Checkbutton(self.editPopup, text = " Important Task? ", command = self.setImportantFlag)
		
		OPTIONS = tuple(self.projectDict.values())
		
		if self.currentTaskType=="Subtask":
			if len(OPTIONS)==0:
				OPTIONS = "None",
		
			variable = StringVar(self.editPopup)
			variable.set(OPTIONS[0]) # default value

			OptionMenu(self.editPopup, variable, *OPTIONS).grid(row=0, column=1, columnspan=2, sticky=W)
			self.variable = variable
			name = Label(self.editPopup, text = "Owning Project ")
			
		else:
			self.nameEntry.grid(row=0, column=1, pady=3, padx = 5, sticky=W, columnspan=2)
		
		
		name.grid(row=0, column=0, pady=3)
		
		description.grid(row=1, column=0, pady=3)
		self.descriptionEntry.grid(row=1, column=1, pady=3, padx = 5, sticky=W, columnspan=2)
		
		hoursCompleted.grid(row=2, column=0, pady=3)
		self.hoursCompletedEntry.grid(row=2, column=1, pady=3, padx = 5, sticky=W, columnspan=2)
		
		hoursTotal.grid(row=3, column=0, pady=3)
		self.hoursTotalEntry.grid(row=3, column=1, pady=3, padx = 5, sticky=W, columnspan=2)
		
		dueDate.grid(row=4, column=0, pady=3)
		self.dueDateEntry.grid(row=4, column=1, pady=3, padx = 5, sticky = W, columnspan=2)
		
		createButton.grid(row=6, column = 0, pady=15, columnspan = 3)
		checkButton.grid(row=4, column=2, sticky=E, pady=5)
	
	def helpCreateTask(self, event):
		self.createTask()

	def updateSubTaskNames(self, task, taskName):
		for listTask in self.taskList:
			if (listTask.name==taskName) and isinstance(listTask, Task.ProjectSubTask):
				listTask.name = task.name
				listTask.setTaskText(False)

	def createTask(self):
		if self.currentTaskType=="Subtask":
			name = self.variable.get()
		else:
			name = self.nameEntry.get()
		description = self.descriptionEntry.get(1.0, END)
		hoursCompleted = self.hoursCompletedEntry.get()
		hoursTotal = self.hoursTotalEntry.get()
		dueDate = self.parseDateTime(self.dueDateEntry.get())
	
		try:
			int(hoursCompleted)
		except:
			hoursCompleted = "0"
		try:
			int(hoursTotal)
		except:
			hoursTotal = "1"

		name = name if len(name) > 0 else ""
		description = description if len(description) > 0 else ""
		hoursCompleted = int(hoursCompleted if (len(hoursCompleted) > 0) else 0 )
		hoursTotal = int(hoursTotal if (len(hoursTotal) > 0) else 1)
		self.addTask(name, description, hoursCompleted, hoursTotal, dueDate)
		self.editPopup.destroy()

	def initializeFrame(self):
		self.tk = Tk()
		self.tk.title('Danner')
		self.tk.resizable(0, 0)
		bottomFrame = Frame(self.tk)
		bottomFrame.pack(side=BOTTOM)
		self.canvas = Canvas(bottomFrame, bg=self.bg, width=self.width, height=self.height)

	
	def calculateLines(self):
		if (len(self.itemList)==0):
			maximum = 2
			minimum = -1
		else:
			maximum = max(self.itemList) + 1 if max(self.itemList) > 1 else 2
			minimum = min(self.itemList)  if min(self.itemList) < -2 else -1
		
		self.lineList = []
		for i in range(1, maximum - minimum + 2): #plus 2 for padding on left and right
			xCoord = self.width * i / (maximum - minimum + 2)
			self.drawLine(xCoord, (maximum + 1 == i), i - 1, maximum)
			self.lineDict[maximum - i] = xCoord
		
	def deleteLines(self):
		for line in self.lineList:
			self.canvas.delete(line)
		for text in self.textList:
			self.canvas.delete(text)
	
	def drawLine(self, xCoord, isDeadline, iteration,  maximum, dash = (2,4) ):
		if isDeadline:
			for i in range(-2, 1):
				line = self.canvas.create_line(xCoord + i,  self.fontsize*2, xCoord + i, self.height, fill=self.lineColor, dash=(1,1))
				self.lineList.append(line)
		else:
			line = self.canvas.create_line(xCoord,  self.fontsize*2, xCoord, self.height, fill=self.lineColor, dash=dash)
			self.lineList.append(line)
		self.drawLabel(xCoord, iteration, maximum)
		return xCoord	
	
	def drawLabel(self, xCoord, iteration, maximum):
		days = (maximum - iteration)
		if days==0:
			days = "DEADLINE"
		text = self.canvas.create_text(xCoord, self.fontsize, text=days, font=("purisa", self.fontsize, "bold"), fill=self.textColor)
		self.textList.append(text)
			
	def addTask(self, name, description, hoursCompleted, hoursTotal, dueDate):
		if self.currentTaskType == "Subtask":
			task = Task.ProjectSubTask(name=name, description=description, hoursCompleted=hoursCompleted, hoursTotal=hoursTotal, dueDate = dueDate, isFlagged = self.isFlagged, panel = self)
			self.updateOwningProject(task.name, True)
		elif self.currentTaskType == "Project":
			task = Task.ProjectTask(name=name, description=description, hoursCompleted=hoursCompleted, hoursTotal=hoursTotal, dueDate = dueDate, isFlagged = self.isFlagged, panel = self)
			self.projectDict[task] = task.name
		elif self.currentTaskType == "Task":
			task = Task.RegTask(name=name, description=description, hoursCompleted=hoursCompleted, hoursTotal=hoursTotal, dueDate = dueDate, isFlagged = self.isFlagged, panel = self)
		self.taskList.append(task)
		self.moveAllTasks()
	
	def updateOwningProject(self, owningTaskName, incrementOrDecrement):
		for project in self.projectDict.keys():
			if self.projectDict[project] == owningTaskName:
				project.changeTotalTasks(incrementOrDecrement)
	
	def setImportantFlag(self):
		self.isFlagged = not self.isFlagged
		
	
	def moveAllTasks(self):
		self.deleteLines()
		self.populateItemList()
		self.calculateLines()
		n = self.calculateTaskPlacement()
		m = n
		for task in self.taskList:
			task.moveCircle(self.lineDict.get(task.daysRemaining, 0), m)
			m += n
		self.lowerLines()
		
	
	def populateItemList(self):
		self.itemList = []
		for task in self.taskList:
			task.daysRemaining = task.calculateDaysRemaining()
			self.itemList.append(task.daysRemaining)
			
	
	def calculateTaskPlacement(self):
		return self.height / ( len(self.taskList) + 1)

	def clearPanel(self):
		for i in range(len(self.taskList)):
			self.taskList[0].deleteTask()
		itemList = []
		projectDict = {}
		self.moveAllTasks()	
   
	def savePanel(self):
		if self.fileName == "":
			self.savePanel2
		saveFileName = self.fileName
		attributeList = self.generateHashableTasks()
		os.system('touch ' + saveFileName)
		s = pickle.dumps(attributeList)
		try:
			fin = open(saveFileName,'w')
			fin.write(s)
			fin.close()
			return True
		except:
			return False		
   
	def savePanel2(self):
		saveFileName = self.askSaveFiles()
		if saveFileName[:-4] != ".txt":
			saveFileName+=".txt"
		self.fileName = saveFileName
		os.system('touch ' + saveFileName)
		attributeList = self.generateHashableTasks()
		s = pickle.dumps(attributeList)
		try:
			fin = open(saveFileName,'w')
			fin.write(s)
			fin.close()
			return True
		except:
			return False

	def generateHashableTasks(self):
		attributeList = []
		for i in range(len(self.taskList)):
			task = self.taskList[i]
			self.currentTaskType = task.taskType
			attributeList.append([task.name, task.description, task.hoursCompleted, task.hoursTotal, task.dueDate, task.isFlagged, task.taskType])
		return attributeList
	
	def openPanel(self):
		fileName = self.askOpenFiles()
		self.fileName = fileName
		f1 = open(fileName)
		self.fileName = fileName.split("/")[0]
		s = ''
		self.clearPanel()
		for line in f1:
			s = s + line
		attributeList = pickle.loads(s)
		for key in attributeList:
			taskType = key
			self.currentTaskType = key[6]
			self.addTask(taskType[0], taskType[1], taskType[2], taskType[3], taskType[4])

	def askOpenFiles(self):
		return askopenfilename(filetypes=[("Text Files","*")])
	
	def askSaveFiles(self):
		filename = asksaveasfilename(filetypes=[("All Files", "*"),("Text Files", "*")])
		self.fileName = filename
		return filename
		
	
	
		
	
if __name__=="__main__":
	panel = Panel()
